#!/usr/bin/env python
# -*- coding: utf-8 -*-

from web.constants.calculation_method import CalculationMethod
from web.constants.direction import Direction
from web.models import CommodityFutureInfo

"""
计算交易费用的工具类
"""


class FeeUtil:

    @staticmethod
    def calculate_open_commodity_future_cost(close_price: float, commodity_future_info: CommodityFutureInfo, lot: int):
        """
        计算期货开仓时的开仓价格
        """

        # 固定值计算
        if commodity_future_info.calculation_method == CalculationMethod.Fixed_Value:
            fee = float(close_price) * float(commodity_future_info.transaction_multiplier) * float(commodity_future_info.company_deposit) * lot
            return fee

        # 费率值计算
        if commodity_future_info.calculation_method == CalculationMethod.Rate_Value:
            fee = float(close_price) * float(commodity_future_info.transaction_multiplier) * float(commodity_future_info.company_deposit) * lot
            return fee

    @staticmethod
    def calculate_open_commodity_future_cost_and_fee(close_price: float, commodity_future_info: CommodityFutureInfo, lot: int):
        """
        计算期货开仓时的全部费用，包括：开仓价格和手续费
        """

        # 固定值计算
        if commodity_future_info.calculation_method == CalculationMethod.Fixed_Value:
            fee = float(close_price) * float(commodity_future_info.transaction_multiplier) * float(commodity_future_info.company_deposit) * lot + \
                  lot * float(commodity_future_info.open_position)
            return fee

        # 费率值计算
        if commodity_future_info.calculation_method == CalculationMethod.Rate_Value:
            fee = close_price * commodity_future_info.transaction_multiplier * commodity_future_info.company_deposit * lot + \
                  close_price * commodity_future_info.transaction_multiplier * commodity_future_info.company_deposit * lot * commodity_future_info.open_position
            return fee

    @staticmethod
    def calculate_open_commodity_future_lot(close_price: float, commodity_future_info: CommodityFutureInfo, fee: float):
        """
        计算期货开仓时的手数
        """

        # 固定值计算
        if commodity_future_info.calculation_method == CalculationMethod.Fixed_Value:
            lot = float(fee) / (float(close_price) * float(commodity_future_info.transaction_multiplier) * float(commodity_future_info.company_deposit) + float(commodity_future_info.open_position))
            return int(lot)

        # 费率值计算
        if commodity_future_info.calculation_method == CalculationMethod.Rate_Value:
            lot = float(fee) / float(close_price * commodity_future_info.transaction_multiplier * commodity_future_info.company_deposit + close_price * commodity_future_info.transaction_multiplier * commodity_future_info.company_deposit * commodity_future_info.open_position)
            return int(lot)

    @staticmethod
    def calculate_open_commodity_future_fee(close_price, commodity_future_info, lot):
        """
        计算期货开仓时的手续费
        """

        # 固定值计算
        if commodity_future_info.calculation_method == CalculationMethod.Fixed_Value:
            return float(lot) * float(commodity_future_info.open_position)

        # 费率值计算
        if commodity_future_info.calculation_method == CalculationMethod.Rate_Value:
            return float(close_price) * float(commodity_future_info.transaction_multiplier) * float(commodity_future_info.company_deposit) * float(lot) * float(commodity_future_info.open_position)

    @staticmethod
    def calculate_close_today_commodity_future_fee(close_price, commodity_future_info, lot):
        """
        计算期货平今仓时的手续费
        """

        # 固定值计算
        if commodity_future_info.calculation_method == CalculationMethod.Fixed_Value:
            fee = lot * commodity_future_info.close_today_position
            return fee

        # 费率值计算
        if commodity_future_info.calculation_method == CalculationMethod.Rate_Value:
            fee = float(close_price) * commodity_future_info.transaction_multiplier * float(commodity_future_info.company_deposit) * lot * float(commodity_future_info.close_today_position)
            return fee

    @staticmethod
    def calculate_close_old_commodity_future_fee(close_price, commodity_future_info, lot):
        """
        计算期货平老仓时的手续费
        """

        # 固定值计算
        if commodity_future_info.calculation_method == CalculationMethod.Fixed_Value:
            fee = lot * commodity_future_info.close_old_position
            return fee

        # 费率值计算
        if commodity_future_info.calculation_method == CalculationMethod.Rate_Value:
            fee = float(close_price) * float(commodity_future_info.transaction_multiplier) * float(commodity_future_info.company_deposit) * float(lot) * float(commodity_future_info.close_old_position)
            return fee

    @staticmethod
    def calculate_actual_profit_and_loss(direction: int, open_price:float, close_price: float, transaction_multiplier: float, lot: int):
        """
        计算实际盈亏（不包括手续费）；
        多头实际盈亏：实际盈亏 = (平仓价 - 买入价) * 合约单位 * 持仓量
        空头实际盈亏：实际盈亏 = (卖出价 - 平仓价) * 合约单位 * 持仓量
        """

        if direction == Direction.Up:
            actual_profit_and_loss: float = (float(close_price) - float(open_price)) * transaction_multiplier * lot
            return actual_profit_and_loss
        if direction == Direction.Down:
            actual_profit_and_loss: float = - (float(close_price) - float(open_price)) * transaction_multiplier * lot
            return actual_profit_and_loss
